home *** CD-ROM | disk | FTP | other *** search
- Subject: Re: GEM apps, in general
- Date: Mon, 25 Jul 1994 10:26:00 +1000
- From: Warwick Allison <warwick@cs.uq.oz.au>
- Precedence: bulk
-
- Michel Forget wrote:
- >Do you have any that shows how
- >to scroll a window using the rectangle list and raster copies? That
- >would be a pretty complex operation, I would think.
-
- This code is from GEM++. Obviously, it's C++, but the guts of it should
- be useful to you. I've added comments on the external function calls.
-
-
- void GEMscrollableobject::Scroll(int pixels_right, int pixels_down)
- {
- if (pixels_down || pixels_right) {
- int X,Y;
- GetAbsoluteXY(X,Y); // ie. use objc_offset to cal object position.
-
- // Walk the rectangle list (form.FirstClip/form.NextClip).
- for (GRect* clip=form.FirstClip(myindex); clip; clip=form.NextClip(clip)) {
- int pxy[8];
-
- // Anything to scroll?
- if (abs(pixels_right)<clip->g_w
- && abs(pixels_down)<clip->g_h) {
- if (pixels_right>0) {
- pxy[0]=clip->g_x+pixels_right;
- pxy[2]=clip->g_x+clip->g_w-1;
- pxy[4]=clip->g_x;
- pxy[6]=clip->g_x+clip->g_w-pixels_right-1;
- } else {
- pxy[0]=clip->g_x;
- pxy[2]=clip->g_x+clip->g_w+pixels_right-1;
- pxy[4]=clip->g_x-pixels_right;
- pxy[6]=clip->g_x+clip->g_w-1;
- }
-
- if (pixels_down>0) {
- pxy[1]=clip->g_y+pixels_down;
- pxy[3]=clip->g_y+clip->g_h-1;
- pxy[5]=clip->g_y;
- pxy[7]=clip->g_y+clip->g_h-pixels_down-1;
- } else {
- pxy[1]=clip->g_y;
- pxy[3]=clip->g_y+clip->g_h+pixels_down-1;
- pxy[5]=clip->g_y-pixels_down;
- pxy[7]=clip->g_y+clip->g_h-1;
- }
-
- ro_cpyfm(VDI::SRC,pxy); // Screen-to-screen raster copy (vro_cpyfm)
-
- if (pixels_right>0) {
- // This is just constructing a rectangle with the given dimensions.
- GRect redraw_side(clip->g_x+clip->g_w-pixels_right,clip->g_y,
- pixels_right,clip->g_h);
-
- RedrawClipped(X,Y,redraw_side); // RedrawClipped is below.
- } else if (pixels_right) {
- GRect redraw_side(clip->g_x,clip->g_y,-pixels_right,clip->g_h);
- RedrawClipped(X,Y,redraw_side);
- }
-
- if (pixels_down>0) {
- if (pixels_right>0) {
- GRect redraw_side(clip->g_x,clip->g_y+clip->g_h-pixels_down,
- clip->g_w-pixels_right,pixels_down);
- RedrawClipped(X,Y,redraw_side);
- } else {
- GRect redraw_side(clip->g_x-pixels_right,clip->g_y+clip->g_h-pixels_down,
- clip->g_w+pixels_right,pixels_down);
- RedrawClipped(X,Y,redraw_side);
- }
- } else if (pixels_down) {
- if (pixels_right>0) {
- GRect redraw_side(clip->g_x,clip->g_y,clip->g_w-pixels_right,-pixels_down);
- RedrawClipped(X,Y,redraw_side);
- } else {
- GRect redraw_side(clip->g_x-pixels_right,clip->g_y,clip->g_w+pixels_right,-pixels_down);
- RedrawClipped(X,Y,redraw_side);
- }
- }
- } else {
- RedrawClipped(X,Y,*clip);
- }
- }
- }
- }
-
- // This is the USEROBJ function (just here to show what RedrawClipped is)
- void GEMscrollableobject::Draw(const PARMBLK* p)
- {
- GRect drawclip(p->pb_xc,p->pb_yc,p->pb_wc,p->pb_hc);
- GRect objclip(p->pb_x,p->pb_y,GEMuserobject::Width(),GEMuserobject::Height());
- drawclip.Clip(objclip);
-
- RedrawClipped(p->pb_x,p->pb_y,drawclip);
- }
-
-
- void GEMcanvas::RedrawClipped(int ox, int oy, const GRect& oarea)
- {
- // White-out the whole area first (some applications don't need this)
- r_recfl(oarea.g_x,oarea.g_y,oarea.g_x+oarea.g_w-1,oarea.g_y+oarea.g_h-1);
-
- // Set VDI clip area
- clip(oarea.g_x,oarea.g_y,oarea.g_x+oarea.g_w-1,oarea.g_y+oarea.g_h-1);
-
- // And just draw whatever is in the window
- GRect area(oarea.g_x-x,oarea.g_y-y,oarea.g_w,oarea.g_h);
- DrawAt(ox-x,oy-y,area);
-
- // Turn of VDI clip
- clip_off();
- }
-
-
-
-
- Hope that's useful to you.
-
-
- --
- Warwick
-